from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
import pymongo

"""
1. omni_listblocktransactions  (1 - now height)
2. omni_gettransaction (txid)  return sender address
3. gettxout (txid) return reviver address
"""


# put data to mongoDB
def put_data_to_mongo(addresses, transaction):
    for address in addresses:
        query = {"addr": address}
        count = mycol.find(query).count()
        if count == 0:
            data = {"addr": address, "trans": [transaction]}
            mycol.insert_one(data)
        else:
            newvalues = {"$push": {"trans": transaction}}
            mycol.update_one(query, newvalues)


if __name__ == '__main__':
    rpc_connection = AuthServiceProxy("http://%s:%s@localhost:18332" % ('username', 'password'))
    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    mydb = myclient["btc_db"]
    mycol = mydb["user2transaction"]

    step = 100
    trans_count = 0

    for height in range(0, 1000000, step):
        # Lists all Omni transactions in a block.
        print(height, height + step)
        transaction = rpc_connection.batch_([["omni_listblockstransactions", height, height + step]])
        len_trans = len(transaction[0])
        trans_count += len_trans
        print('current height = ', height, '   current trans count = ', len_trans, 'total count = ', trans_count)

        if len_trans > 0:
            print(transaction)
            # get transaction by omnicore
            txs = [["omni_gettransaction", txid] for txid in transaction[0]]
            transactions = rpc_connection.batch_(txs)
            trans_list = []
            for res in transactions:
                txid = res['txid']
                sender = res['sendingaddress']
                trans_list.append([sender, txid])

            # get transaction by bitcoinCore
            txs = [["getrawtransaction", txid] for txid in transaction[0]]
            raw_trans = rpc_connection.batch_(txs)
            txs = [["decoderawtransaction", raw] for raw in raw_trans]
            vouts = rpc_connection.batch_(txs)
            vout_list = []
            for vout in vouts:
                vout_set = set()
                for v in vout['vout']:
                    vout_set = vout_set | set(v['scriptPubKey']['addresses'])
                vout_list.append(vout_set)

            # put data to mongo
            for x, y in zip(trans_list, vout_list):
                address = set(y)
                address.add(x[0])
                value = x[1]
                put_data_to_mongo(address, value)
